
#import "WW3DBox.h"
#import "RIBPointsPolygons.h"

@implementation WW3DBox

+ initialize { return [WW3DBox setVersion:1], self; }

- assignPoints
{
  points[0][0] = xMin;
  points[0][1] = yMax;
  points[0][2] = zMax;

  points[1][0] = xMax;
  points[1][1] = yMax;
  points[1][2] = zMax;

  points[2][0] = xMax;
  points[2][1] = yMax;
  points[2][2] = zMin;

  points[3][0] = xMin;
  points[3][1] = yMax;
  points[3][2] = zMin;

  points[4][0] = xMin;
  points[4][1] = yMin;
  points[4][2] = zMax;

  points[5][0] = xMax;
  points[5][1] = yMin;
  points[5][2] = zMax;

  points[6][0] = xMax;
  points[6][1] = yMin;
  points[6][2] = zMin;

  points[7][0] = xMin;
  points[7][1] = yMin;
  points[7][2] = zMin;

  dirtyBoundingBox = TRUE;

  return self;
}

- init
{
  [super init];

  nPolys = 6;

  nVerts[0] = nVerts[1] = nVerts[2] = nVerts[3] = nVerts[4] = nVerts[5] = 4;

  verts[0] = 3;   verts[1] = 2;   verts[2] = 6;   verts[3] = 7;
  verts[4] = 2;   verts[5] = 1;   verts[6] = 5;   verts[7] = 6;
  verts[8] = 1;   verts[9] = 0;   verts[10] = 4;  verts[11] = 5;
  verts[12] = 0;  verts[13] = 3;  verts[14] = 7;  verts[15] = 4;
  verts[16] = 7;  verts[17] = 6;  verts[18] = 5;  verts[19] = 4;
  verts[20] = 0;  verts[21] = 1;  verts[22] = 2;  verts[23] = 3;

  xMin = -1.0;
  xMax =  1.0;
  yMin = -1.0;
  yMax =  1.0;
  zMin = -1.0;
  zMax =  1.0;

  [self assignPoints];

  return self;
}


- setXMin:(RtFloat)newXMin xMax:(RtFloat)newXMax 
     yMin:(RtFloat)newYMin yMax:(RtFloat)newYMax 
     zMin:(RtFloat)newZMin zMax:(RtFloat)newZMax 
     n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
     printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
{  
   id  boxObj;


   xMin = newZMin;
   xMax = newZMax;
   yMin = newZMin;
   yMax = newZMax;
   zMin = newZMin;
   zMax = newZMax;

   [ribCommandList empty];

   boxObj = [[RIBPointsPolygons alloc] init]; 
   [boxObj setXMin:xMin xMax:xMax yMin:yMin yMax:yMax zMin:zMin zMax:zMax
                    n:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
   [boxObj setMyShape:myShape];

   [ribCommandList insertObject:boxObj at:0];

   [self assignPoints];
  
   return self;
}

- setXMin:(RtFloat)newXMin { xMin = newXMin; [self assignPoints]; return self; }
- setXMax:(RtFloat)newXMax { xMax = newXMax; [self assignPoints]; return self; }
- setYMin:(RtFloat)newYMin { yMin = newYMin; [self assignPoints]; return self; }
- setYMax:(RtFloat)newYMax { yMax = newYMax; [self assignPoints]; return self; }
- setZMin:(RtFloat)newZMin { zMin = newZMin; [self assignPoints]; return self; }
- setZMax:(RtFloat)newZMax { zMax = newZMax; [self assignPoints]; return self; }

- (RtFloat)xMin { return xMin; }
- (RtFloat)xMax { return xMax; }
- (RtFloat)yMin { return yMin; }
- (RtFloat)yMax { return yMax; }
- (RtFloat)zMin { return zMin; }
- (RtFloat)zMax { return zMax; }

// WavesWorld archiving:
// writeEve:(NXStream *)stream
// writeScene:(NXStream *)stream

- writeEve:(NXStream *)stream atTabLevel:(int)tab
{
    int  i;
    
    for (i = 0; i < tab; i++) {
	NXPrintf(stream, "\t");
    }
    NXPrintf(stream, "WW3DBox %f %f %f %f %f %f", xMin, xMax, yMin, yMax, zMin, zMax);
    return self;
}

- writeScene:(NXStream *)stream atTabLevel:(int)tab
{
   return [self writeEve:stream atTabLevel:tab];
}

- write3DTextScene:(NXStream *)stream atTabLevel:(int)tab index:(int)index time:(float)time until:(float)lastTime
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }

   NXPrintf(stream, "startShape %s; ", [[self class] name]);
   // need tab
   // need index (position in current list)
   NXPrintf(stream, 
	    "EveCmd {Translate [expr { %d * $__text__(tabLength)}] [expr {$__text__(spacingFactor) * %d * $__text__(spacing) * $__text__(fontSize)}] 0 };\n", 
            tab, index); 
   NXPrintf(stream, "  EveCmd {WW3DText $__text__(fontName) $__text__(fontSize) {");
   [self writeEve:stream atTabLevel:tab];
   NXPrintf(stream, "} left;}\n");
  NXPrintf(stream, "endShape;\n");

  return self;
}

- writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
{
   int  i;


   for (i = 0; i < tab; i++)
   {  NXPrintf(stream, "\t");
   }
   NXPrintf(stream, "# ");
   [self writeEve:stream atTabLevel:tab];
   NXPrintf(stream, "\n");

   return [ribCommandList writeInventorAtTime:currentTime to:stream atTabLevel:tab];
}


#define typeVector "@ffffff"
#define typeValues &ribCommandList, &xMin, &xMax, &yMin, &yMax, &zMin, &zMax

- read:(NXTypedStream *)stream 
{
    int version;
    
    [super read:stream];
    version = NXTypedStreamClassVersion(stream,"WW3DBox");
    if (version == 0) NXReadTypes(stream, "i", &version), version = 1;
    if (version == 1)
    {  NXReadTypes(stream, typeVector, typeValues);
       NXReadArray(stream, "f", 6, boundingBox);
       myShape = NXReadObject(stream);
    }

    return self;
}

- write:(NXTypedStream *)stream 
{
    [super write:stream];
    NXWriteTypes(stream, typeVector, typeValues);
    NXWriteArray(stream, "f", 6, boundingBox);
    NXWriteObjectReference(stream, myShape);
    return self;
}

- (BOOL)theSameAs:otherRIBCommand
{
  // WAVE: really should try and return YES, but for now...
  return NO;
}

- (BOOL)isMoot
{
  return NO;
}

- (BOOL)isMootStartingAt:(float)startTime endingAt:(float)endTime  {  return [self isMoot];  }

// boy, this is dumb... This is to get around the stupid warnings from the compiler - ask wave for details
- class { return [super class]; }



@end
